Добавил:
Developer Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа №1 ТПП

.docx
Скачиваний:
0
Добавлен:
29.04.2024
Размер:
290.6 Кб
Скачать

Министерство цифрового развития, связи и массовых коммуникаций Российской Федерации

Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования

«Московский технический университет связи и информатики»

(МТУСИ)

Кафедра: «Математическая кибернетика и информационные технологии»

Индивидуальная работа

Дисциплина: «Тестирование программных продуктов»

по теме:

«Оценка сложности простых программ по метрикам Холстеда и Джилба»

Выполнили: студенты

_________________________

Проверил:

Говоров Павел Михайлович

_________________________

Москва, 2026

Цель

Изучение средств оценки простой программы на языке С++.

Задание

Для программы на языке С++ произвести расчет метрик Холстеда и Джилба. В случае наличия ошибок в программе, оформить их отдельно в табличном виде.

Ход выполнения работы

Метрика Холстеда относится к метрикам, вычисляемым на основании анализа числа строк и синтаксических элементов исходного кода программы. Метрики Холстеда отражают лексический подход к измерению характеристик программного обеспечения, основанный на измеримых свойствах алгоритмов. Свойства любого описания алгоритма (или программы для ЭВМ), по мнению Холстеда, могут быть измерены или вычислены на основе конкретных метрических характеристик.

Еще одним типом метрик ПО, относящихся к количественным, являются метрики Джилба. Они показывают сложность программного обеспечения на основе насыщенности программы условными операторами или операторами цикла. Данная метрика, не смотря на свою простоту, довольно хорошо отражает сложность написания и понимания программы, а при добавлении такого показателя, как максимальный уровень вложенности условных и циклических операторов, эффективность данной метрики значительно возрастает.

На рисунке 1.1.1 – 1.1.2 изображена блок-схема функции программы main(void), код которого представлен на листинге 1.1.

Рисунок 1.1.1 – Блок схема функции main 1 часть

Рисунок 1.1.1 – Блок схема функции main 2 часть

На рисунке 1.1.3 изображена блок-схема функции программы print_ar(double ar[N][N], double size, string name), код которого представлен на листинге 1.1.

Рисунок 1.1.3 – Блок схема функции print _ar

На рисунке 1.1.4 изображена блок-схема функции программы min(double x, double y), код которого представлен на листинге 1.1.

Рисунок 1.1.3 – Блок схема функции min

На рисунке 1.1.4 изображена блок-схема функции программы max_of_five(double* ar, int size), код которого представлен на листинге 1.1.

Рисунок 1.1.4 – Блок схема функции max_of_five

Код программы представлен в листинге 1.

#define N 3

double min(double x, double y);

double max_of_five(double* ar, double size); //функция вывода двумерных массивов

void print _ar(double ar[N][N], double size, string name)

{

cout << name << endl;;

for (int i = 0; i < size; i++)

{

for (int j = 0; j < size; j++)

{

cout << ar[i][j] << " ";

}

cout << endl;

}

cout << endl;

}

int main(void)

{

double ar1[N][N];

double ar2[N][N];

double ar3[N][N];

double arr[N];

double arrr[N];

double val;

int i, j;

// заполнение элементами первого двумерного массива

cout << "Enter the elements of matrix l" << endl;

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

cin >> val;

ar1[i][j] = val;

}

}

//заполнение элементами второго двумерного массива

cout <<"Enter the elements of matrix 2" << endl;

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

cin >> val;

ar2[i][j] = val;

}

}

//нахождение минимальных значений и заполнение ими третьего двумерного массива

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

ar3[i][j] = min(ar1[i][j],ar2[i][j]);

}

}

//вывод первого и второго массива

print_ar(ar1, N, "Matrix 1");

print_ar(ar2, N, "Matrix 2");

// нахождение максимльного значения

for (i = 0; i < N; i++)

{

for (i = 0; j < N; j++)

{

arrr[i] = max(ar3[i][j], ar3[i][j + 1]);

}

}

//продолжение нахождения максимального значения, заполнение его в одномерный массив и вывод

cout <<"result" <<endl;

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

arrr[i] = max(arr[i][j], ar3[i][j + 2]);

}

cout << arr[i] «< endl;

}

}

double min(double x, double y)

{

it (x < y) return x;

return y;

}

double max_of_five(double* ar, double size)

{

double max = ar [0];

for (int i = 0; i < size; i++)

{

if (ar[i] > max)

max = ar[i];

}

return max;

}

Результат запуска программы представлен на рисунке 1.2

Рисунок 1.2 - Результат запуска программы

Расчет словаря операторов для метрики Холстеда представлен в таблице 1.1.

Таблица 1.1 Расчет метрики Холстеда (словарь операторов)

Операторы, операции

Номера строк

Количество

=

7,9, 28, 30,33,38,40,43,47,49,51,58,60,62,67,69,71,85,86,89

20

++

7,9,28,30,38,40,47,49,58,60,67,69,86

13

+

71

1

>

88

1

<

28,30,38,40,47,49,58,60,67,69,79,86

12

>>

32,42

2

<<

6(2), 11(2), 13,15,27 (2), 37(2), 66(2), 73(2)

14

Обращение к элементу массива (a[b])

19,20,21,22,23,33, 51 (3),62(3),71(3), 73,85,88,89

19

Непрямое обращение (*a)

3,83

2

() – вызов функции

2,3,4,17,55,56,77,83

8

If…else

79,88

2

For {}

7,9,28,30,38,40,47,49,58,60,67,69,86

13

Cout

6,11,13,15,27,37,66,73

8

endl

6,13,15,27,37,66,73

7

return

79,80,91

3

Итого (15 простых оператора)

125

Расчет словаря операндов для метрики Холстеда представлен в таблице 1.2.

Таблица 1.2 Расчет метрики Холстеда (словарь операндов)

Операнд

Номера строк

Количество

x

2,79 (2)

3

y

2,79,80

3

ar[]

11,85,88,89

4

size

7,9,86

3

name

6

1

i

7(3),11,25,28(3),33,38(3),43,47(3),51(3),58(3),62(3),67(3), 71(3),73, 86(3),88,89

37

j

9(3),11,25,30(3),33,40(3),43,49(3),51(3),60(3),62(2),69(3), 71(2)

29

ar1[][]

33,51

2

ar2[][]

43,51

2

ar3[][]

51,62 (2),71

4

arr[]

71,73

2

arrr[]

62,71

2

N

1, 4(2), 19(2),20(2),21(2),22,23,28,30,38,40,47,49,58,60,67,69

21

"Enter the elements of matrix l"

27

1

"Enter the elements of matrix 2"

37

1

"result"

66

1

Итого (16 простых операндов)

116

Входные и выходные параметры представлены в таблице 1.3.

Таблица 1.3 Входные и выходные параметры

Входные параметры

Выходные параметры

x

max

y

ar

size

name

Расчет итоговых характеристик представлен в таблице 1.4

Таблица 1.4 Расчет итоговых характеристик

Характеристика

Формула для вычисления

Значение

Число простых (уникальных) операторов и операций

n1

15

Число простых (уникальных операндов)

n2

16

Общее число всех операторов и операций

N1

125

Общее число всех операндов

N2

116

Общее число входных и выходных переменных

n*2

6

Словарь программы

n= n1 + n2

31

Длина реализации

N*= N1 + N2

241

Длина программы

N= n1 * log2 n1 + n2 * log2 n2

122,6

Объем программы (в битах)

V=N* * log2 n

1205

Потенциальный объем программы

V* = (n*2 +2) * log2 (n*2 +2)

24

Уровень реализации программы

L= V* /V

0,02

Уровень языка

=L* V*

0,48

Работа по программированию

E=V/L

60250

Выводы по расчету: длина реализации в два раза превышает длину программы, что говорит о низком качестве кода. При этом уровень реализации программы очень низкий, так как потенциальный объем программы существенно меньше реального, следовательно, возможности языка программирования использованы на низком уровне.

Далее выполним расчет метрики Джилба. В программе использовалось 2 логических оператора и 125 операторов использовалось во всей программе. Следовательно:

CL =2;

CJ = 2/125= 0,016

Расчет отражает легкую структуру кода, так как были найдены только 2 ветвления, что подтверждается низким значением метрики относительной сложности программы.

Ошибки, которые были зарегистрированы в ходе тестирования программы отражены в таблице 3.

Таблица 3. Ошибки, обнаруженные в программе

Строка ошибок

Пояснение

Номер строки

Тип ошибки

#include <iostream>

#include <string>

using namespace std;

Добавлены библиотеки для возможности запуска программы

1,2,3

Компиляционная

void print_ar(double ar[N][N], int size, string name)

Неверный тип данных – размер массива может быть только целочисленным значением (заменить double size на int size)

8

Несоответствие типа данных

double max_of_five(double* ar, int size)

Неверный тип данных – размер массива может быть только целочисленным значением (заменить double size на int size)

7,82

Несоответствие типа данных

cout << "Enter the elements of matrix 1" << endl;

Исправлено сообщение о вводе элементов для матрицы 1 (исправлен символ l на 1)

31

arrr[i] = max(arr[i][j], ar3[i][j + 2])

Функция неправильная находит максимальный элемент в массиве, изменили на функцию arrr[i] = max (&ar3[i], N);

64

логическая

ar1[i][j] = val;

Добавлена проверка на ввод не корректных значений и вывод ошибки с последующим завершением программы

33

логическая

Кода после исправления найденных ошибок представлен в листинге 2.

Листинг 2. Код после исправления ошибок

#include <iostream>

#include <string>

using namespace std;

#define N 3

double min(double x, double y);

double max_of_five(double* ar, int size); // функция поиска максимального значения в массиве

void print_ar(double ar[N][N], double size, string name) //функция вывода двумерных массивов

{

cout << name << endl;

for (int i = 0; i < size; i++)

{

for (int j = 0; j < size; j++)

{

cout << ar[i][j] << " ";

}

cout << endl;

}

cout << endl;

}

int main(void)

{

double ar1[N][N];

double ar2[N][N];

double ar3[N][N];

double arr[N];

double arrr[N];

double val;

int i, j;

//заполнение элементами первого двухмерного массива

cout << "Enter the elements of matrix 1" << endl;

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

cin >> val;

if (double(val)) // Добавил проверку если возможно преобразовать double

ar1[i][j] = val;

else

{

cout << "The entered value in the array is not a number" << endl; //Выведет ошибку, что не может преобразовать в число

return 0; // завершает выполнение программы

}

}

}

//заполнение элементами второго двухмерного массива

cout << "Enter the elements of matrix 2" << endl;

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

cin >> val;

ar2[i][j] = val;

}

}

//нахождение минимальных значений и заполнение ими третьего двухмерного массива

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

ar3[i][j] = min(ar1[i][j], ar2[i][j]);

}

}

//вывод первого и второго массива

print_ar(ar1, N, "Matrix 1");

print_ar(ar2, N, "Matrix 2");

//нахождение максимального значения

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

arrr[i] = max(ar3[i][j], ar3[i][j + 1]);

}

}

//продолжение нахождение максимального значения, заполнение его в одномерный массив и вывод

cout << "result" << endl;

for (i = 0; i < N; i++)

{

for (j = 0; j < N; j++)

{

arr[i] = max_of_five(&ar3[i][j], N); //изменили на функцию max_of_five(&ar3[i][j], N)

}

cout << arr[i] << endl;

}

return 0; //добавили return 0

}

double min(double x, double y)

{

if (x < y) return x;

return y;

}

double max_of_five(double* ar, int size)

{

double max_val = ar[0]; //Изменили переменную на max_val

for (int i = 0; i < size; i++) {

if (ar[i] > max_val)

max_val = ar[i];

}

return max_val;

}

Результат выполнения исправленной программы представлен на рисунке 2.

Рисунок 2 - Результат выполнения исправленной программы

Модель Шумана

  • Относится к динамическим моделям дискретного времени.

  • Данные для такой модели собираются в процессе тестирования программного обеспечения в течение фиксированных или случайных интервалов времени.

  • Предполагает, что тестирование проводится в несколько этапов.

  • Каждый этап представляет собой выполнение программы на полном комплексе тестовых данных.

  • Выявленные ошибки регистрируются.

Данные из нашей программы:

Таблица 5. Расчет модели Шумна (словарь операторов)

Операторы, операции

Количество

=

20

++

13

+

1

>

1

<

12

>>

2

<<

14

Обращение к элементу массива (a[b])

19

Непрямое обращение (*a)

2

() – вызов функции

8

If…else

2

For {}

13

Cout

8

endl

7

return

3

Итого (15 простых оператора)

125

Таким образом общее число машинных команд I = 125

№ Прогона

1

2A

3

4

5

6

7

8B

9

10

Количество ошибок

8

1

1

1

1

1

0

0

0

0

Время прогона (с)

5

4

5

4

3

3

2

2

2

1

Количество ошибок до тестирования E = 8

Время тестирования на интервале A и B

Удельное количество ошибок в расчете на одну команду на интервалах А и В:

Интенсивность ошибок на интервалах:

Коэффициент пропорциональности

Модель Миллса

  • Модель относится к статическим моделям (т.е. не учитывается время тестирования);

  • Позволяет оценить не только количество ошибок до начала тестирования, но и степень отлаженности программы;

  • Для применения модели до начала тестирования в программу преднамеренно вносятся ошибки;

  • Далее считают, что обнаружение преднамеренно внесенных ошибок и так называемых собственных ошибок равновероятно;

Для оценки числа ошибок до начала тестирования используется выражение:

,

Где:

W – число искусственно внесенных ошибок;

S – число собственных ошибок;

V – число обнаруженных в процессе тестирования ошибок из числа преднамеренно внесенных.

В программе, которая рассматривается в лабораторной работе всего было внесено 5 искусственных ошибок. В процессе тестирования обнаружены все искусственно внесенные ошибки и 3 собственных. Тогда число ошибок до тестирования равно:

Степень отлаженности программы можно определить по формуле:

Где:

W – число искусственно внесенных ошибок;

S – число собственных ошибок;

R – число обнаруженных ошибок в программе;

Для программы из лабораторной работы:

Таким образом, согласно модели Миллса, степень отлаженности программы из лабораторной работы 0,56.

Метрики Чепина

Метрики Чепина позволяют исходя из анализа типа переменных, используемых в программе сделать вывод о сложности программы.

Все переменные разбиваются на следующие типы:

  • P – вводимые для расчета переменные и обеспечивающие вывод данных переменные;

  • M - модифицируемые в программе переменные или созданные внутри программы переменные;

  • С – переменные, участвующие в управлении работой программы;

  • T – не используемые в программе переменные;

В качестве особенности применения данной метрики следует назвать необходимость учета каждой переменной в каждой функциональной группе, поскольку каждая переменная может выполнять одновременно несколько функций. Исходное выражение для определения метрики Чепина записывается в следующем виде:

Q = а1 *Р + а2 * М + a3 * С + а4 * Т

Где a1, a2, a3, a4 – весовые коэффициенты.

Чепин предложил (исходя из опыта анализа различных программ) следующие весовые коэффициенты: a1=1, a2= 2, a3=3, a4 =0,5.

Тогда метрика будет вычисляться по формуле:

Q= P + 2*M + 3* C + 0,5 * T

Для программы, рассматриваемой в лабораторной работе:

Q= 6 + 2*7 + 3* 4 + 0,5 * 0= 32

Значение метрики Чепина достаточно высокое, что говорит о излишнем использовании переменных внутри программы.

Вывод

В ходе лабораторной работы был проанализирован данный код на языке С++, нарисована блок-схема, продемонстрирован результат работы программы и рассчитаны метрики Холстеда и Джилба. Расчет метрики Холстеда показал, что длина реализации в два раза превышает длину программы, что говорит о низком качестве кода. При этом уровень реализации программы очень низкий, так как потенциальный объем программы существенно меньше реального, следовательно, возможности языка программирования использованы на низком уровне. Низкое значение метрики Джилба показало легкую структуру кода.

После анализа кода и расчета метрик, в программе было зарегистрировано ряд ошибок и последующее их исправление.